`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////Asyncsys Lab////////////////////////////////////////
// Author: Zhenbang Kang
// Email: kangzhb20@lzu.edu.cn
// Create Date: 2022/06/10 
// Module Name: dcache_control
// Project Name: ac8051 (Asynchronous Click 8051)
// Target Devices: XC7A100TFGG484-2
// Tool Versions: Vivado 2019.1
// Description:Dcache Module
// Revision: V2.0
//////////////////////////////////////////////////////////////////////////////////

module dcache_control(
//        rst_n,
        in_R_rst,
        in_R_delay_final1,
        in_R_delay_final3,
//        out_A_click3,
        ram_data_out,
        ram_addr,
        ram_wen,
        fire_ext_sram,
        in_A_dcache_read,
        out_R_dcache_read,
        in_A_dcache_write,
        out_R_dcache_write,      
        ram_data_in
    );
//	 input            rst_n;
	 input            in_R_rst;
     input            in_R_delay_final1;
     input            in_R_delay_final3;
//     input            out_A_click3;
     input    [7:0]   ram_data_out;
     input    [7:0]   ram_addr;
     input            ram_wen;
     input            fire_ext_sram;
     output           in_A_dcache_read;
     output           out_R_dcache_read;
     output           in_A_dcache_write;
     output           out_R_dcache_write;      
     output   [7:0]   ram_data_in;
		
//wire            rst_n;
wire            in_R_rst;
(* dont_touch = "true" *)wire            in_R_delay_final1;
(* dont_touch = "true" *)wire            in_R_delay_final3;
(* dont_touch = "true" *)wire            out_A_click3;
(* dont_touch = "true" *)wire    [7:0]   ram_data_out;
(* dont_touch = "true" *)wire    [7:0]   ram_addr;
(* dont_touch = "true" *)wire            ram_wen;
wire            fire_ext_sram;
(* dont_touch = "true" *)wire            in_A_dcache_read;
(* dont_touch = "true" *)wire            out_R_dcache_read;
(* dont_touch = "true" *)wire            in_A_dcache_write;
(* dont_touch = "true" *)wire            out_R_dcache_write;
(* dont_touch = "true" *)reg            out_A_dcache_write;      
(* dont_touch = "true" *)wire    [7:0]   ram_data_in;	

wire    fire_out_read;
wire    fire_out_write;
wire    fire_out_write_inv;
wire    fire_sum;
(* dont_touch = "true" *)wire             dcache_wea;
  assign dcache_wea = ~ram_wen;
//(* keep_hierarchy = "yes" *)click_interact_dcache dcache_read(
//                    .in_R           (  in_R_delay_final1  ),
//                    .out_A          (  out_A_click3       ),
////                    .rst_n          (        rst_n        ),
//                    .in_A           (  in_A_dcache_read   ),
//                    .out_R          (  out_R_dcache_read  ),
//                    .fire_out       (  fire_out_read      )
//    );
(* keep_hierarchy = "yes" *)click_dcache_read dcache_read(
                    .in_R(in_R_delay_final1),
                    .in_R_rst(in_R_rst),
//                    rst_n,
                    .in_A(in_A_dcache_read),
                    .out_R(out_R_dcache_read),
                    .fire_out(fire_out_read));
(* keep_hierarchy = "yes" *)click_interact_dcache dcache_write(
                    .in_R           (  in_R_delay_final3  ),
                    .out_A          (  out_A_dcache_write ),
//                    .rst_n          (        rst_n        ),
                    .in_A           (  in_A_dcache_write  ),
                    .out_R          (  out_R_dcache_write ),
                    .fire_out       (  fire_out_write     )
    );
    assign fire_out_write_inv = ~fire_out_write;
    assign fire_sum = fire_out_read | fire_out_write | fire_ext_sram;
    always@(posedge fire_out_write_inv or negedge in_R_rst)begin
        if(!in_R_rst)begin
            out_A_dcache_write <= 'b0;
        end else begin
            out_A_dcache_write <= out_R_dcache_write;
        end
    end
    
//    assign out_A_dcache_write = out_R_dcache_write;
//    sram #( .data_width(8), .data_depth(256), .addr_width(8))
//             u_sram(.fire(fire_sum),.data(ram_data_out),.addr(ram_addr),.cen(1'b0),.wen(ram_wen),.Q(ram_data_in));
(* keep_hierarchy = "yes" *)blk_mem_gen_1 dcache(
                .clka(fire_sum),
                .ena(1'b1),
                .wea(dcache_wea),
                .addra(ram_addr),
                .dina(ram_data_out),
                .douta(ram_data_in)
                );
endmodule
